<script lange="jsx">
import utils from '@/utils'
import pagination from '@/mixins/crud-pagination'
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
export default {
    name: 'table-compontent',
    mixins: [pagination],
    components: {},
    props: {
        selection: {
            type: Boolean,
            default: false
        },
        code: {
            type: String,
            default: ''
        },
        isindex: {
            type: Boolean,
            default: false
        },
        settingColumns: {
            type: Array,
            default: () => []
        },
        settingSearch: {
            type: Array,
            default: () => []
        },
        api: {
            type: String,
            default: ''
        },
        queryPermission: {
            type: String,
            default: ''
        },
        searchValue: {
            type: Object,
            default: () => {}
        },
        isDefaultSearch: {
            type: Boolean,
            default: true
        },
        isPagination: {
            type: Boolean,
            default: true
        },
        tableData: {
            type: Array,
            default: () => []
        },
        resetShow: {
            type: Boolean,
            default: true
        },
        export: {
            type: Boolean,
            default: false
        },
        tbtit: {
            type: String,
            default: '导出'
        }
    },

    data() {
        return {
            // 主体表格
            table: {
                data: [],
                columns: []
            },
            // 表格列设置
            columnSetting: [],
            // 表格展示的token
            tableShow: false,
            // 行高改变的一些字段
            targetTd: null,
            coltargetTd: null,
            resizeable: false,
            mousedown: false,
            // 搜索
            search: {
                panel: {
                    active: true
                },
                form: {
                    model: {},
                    size: 'mini',
                    inline: true
                }
            },
            // 排序
            sort: {
                prop: '',
                type: ''
            },
            // 主体表格列过滤
            columnsFilter: {
                options: []
            },
            // 页面状态
            status: {
                isLoadingData: false,
                isLoadingDict: false
            },
            tableLoading: false,
            tableResult: {}
            // all_num: ''
        }
    },
    watch: {
        settingColumns: 'initTableColumns',
        searchValue: {
            handler(newData) {
                this.$set(this.search.form, 'model', {
                    ...this.search.form.model,
                    ...newData
                })
            },
            deep: true,
            immediate: true
        },
        tableData: {
            handler(newData) {
                // if (!this.isDefaultSearch) {
                this.$set(this.table, 'data', this.tableData)
                // }
            },
            deep: true,
            immediate: true
        }
    },
    computed: {
        vNodeSearchForm() {
            const node = (
                <el-form
                    {...{ attrs: this.search.form }}
                    class="is-thin search">
                    {this.settingSearchFilteredShow.map(item => {
                        const input = item.render
                        const formItem = [
                            <el-form-item label={item.label} prop={item.prop}>
                                {input}
                            </el-form-item>,
                            item.divider === false ? null : (
                                <el-divider direction="vertical"></el-divider>
                            )
                        ]
                        return formItem
                    })}
                    {this.settingSearchFilteredShow.length ? (
                        <el-form-item label="操作" class="table-search-actions">
                            {this.vNodeButtonSearchInForm}
                            {this.vNodeButtonSearchFormResetInForm}
                            {this.export ? this.vNodeButtonExportExcel : null}
                            {this.vNodeButtonTableColumnsFilterTrigger}
                        </el-form-item>
                    ) : null}
                </el-form>
            )
            return node
        },
        // vNode
        // 搜索按钮
        // 搜索表单中的搜索按钮
        vNodeButtonSearchInForm() {
            const node = (
                <el-button
                    icon="el-icon-search"
                    type="primary"
                    loading={this.isSearchButtonLoading}
                    on-click={() => this.research(false)}
                    thin>
                    搜索
                </el-button>
            )
            return node
        },
        // vNode
        // 导出表格
        // 表格中数据导出
        vNodeButtonExportExcel() {
            const node = (
                <el-button
                    icon="el-icon-download"
                    type="primary"
                    loading={this.isSearchButtonLoading}
                    on-click={() => this.exportExcel()}
                    thin>
                    {this.tbtit}
                </el-button>
            )
            return node
        },
        // vNode
        // 搜索表单中的重置按钮
        vNodeButtonSearchFormResetInForm() {
            const node = (
                <el-button
                    icon="el-icon-refresh"
                    on-click={() => this.searchFormReset()}
                    plain
                    thin>
                    重置
                </el-button>
            )
            return node
        },
        // vNode
        // 搜索按钮
        // 顶栏始终显示的搜索按钮
        vNodeButtonSearch() {
            const node = (
                <el-button
                    icon="el-icon-refresh"
                    loading={this.isSearchButtonLoading}
                    on-click={() => this.research(true)}>
                    刷新
                </el-button>
            )
            return node
        },
        // vNode
        // 列过滤触发按钮
        vNodeButtonTableColumnsFilterTrigger() {
            const node = (
                <el-button
                    icon="el-icon-set-up"
                    on-click={() => this.tableColumnsFilterStart()}>
                    设置
                </el-button>
            )
            return node
        },
        // vNode
        // 表格列设置
        vNodeTableColumnsFilter() {
            const node = (
                <table-columns-filter
                    ref="table-columns-filter"
                    {...{ attrs: this.columnsFilter }}
                    vModel={this.table.columns}
                />
            )
            return node
        },
        // vNode
        // 新建按钮
        vNodeSearchPanelAlertNoPermissionQuery() {
            const node = (
                <el-alert
                    title="无查询权限 请联系管理员"
                    type="error"
                    closable={false}
                    style={{
                        padding: '5px 20px'
                    }}
                    center
                />
            )
            return node
        },
        // 建议的书写顺序 [prop] -> [label] -> [align] -> [minWidth][width] -> [fixed] -> [other] -> [render][formatter] -> [if][show]
        // settingColumns() {
        //     return []
        // },
        // 配置项
        // 表格操作列配置
        settingActionsConfig() {
            return () => []
        },

        // 表单设置
        // 过滤掉不显示的字段
        settingSearchFilteredShow() {
            return this.settingSearch.filter(item => item.show !== false)
        },
        // 搜索按钮 loading 状态
        // 正在加载原始数据 || 正在加载字典
        isSearchButtonLoading() {
            return this.status.isLoadingData || this.status.isLoadingDict
        },
        // 表格 loading 状态
        // 正在加载原始数据 || 正在加载字典
        isTableLoading() {
            return this.status.isLoadingData || this.status.isLoadingDict
        },
        // 自动整合 [搜索项] [分页设置] [排序]
        searchData() {
            return {
                ...this.search.form.model,
                ...(this.paginationSearchData || {}),
                order_column_name: this.sort.prop,
                order_type: this.sort.type
            }
        }
    },
    async created() {
        // this.initSearchForm()
        this.initTableColumns()

        this.isDefaultSearch && this.research(true)
    },
    mounted() {
        // this.tableShow = true
        // setTimeout(() => {
        //     this.$nextTick(() => {
        //         this.tableInit()
        //     })
        // }, 1000)
    },
    methods: {
        async getColumnSetting() {
            if (this.code) {
                const data = await this.$api.GET_TABBLECOLUMN({
                    code: this.code
                })
                return data || []
            } else {
                return []
            }
        },
        /**
         * @description 搜索方法 这个方法可以在外部自定义
         * @returns 数据
         */
        searchMethod() {
            console.log('进入table数据请求--------------', this.api)
            const method = this.$api[this.api]
            if (!this._.isFunction(method)) {
                this.$message.error('未找到 API')
                return Promise.reject(new Error('未找到 API'))
            }
            return method(this.searchData)
        },
        exportExcel() {
            this.$emit('exportTable')
            // this.paginationUpdateSize(this.all_num)
            // var xlsxParam = { raw: true } //转换成excel时，使用原始的格式
            // /* out-table关联导出的dom节点 */
            // var wb = XLSX.utils.table_to_book(this.$refs.table.$el, xlsxParam)
            // /* get binary string as output */
            // var wbout = XLSX.write(wb, {
            //     bookType: 'xlsx',
            //     bookSST: true,
            //     type: 'array'
            // })
            // try {
            //     FileSaver.saveAs(
            //         new Blob([wbout], {
            //             type: 'application/octet-stream;charset=utf-8'
            //         }),
            //         '数据.xlsx'
            //     )
            // } catch (e) {
            //     if (typeof console !== 'undefined') {
            //         console.log(e, wbout)
            //     }
            // }

            // return wbout
        },
        /**
         * @description 加载数据
         */
        async research(isResetPage = false) {
            try {
                // if (
                //     !this.queryPermission ||
                //     !this.$permission(this.queryPermission)
                // ) {
                //     return
                // }
                // 表格显示无需等待字典加载完成 所以这里不需要 await
                // this.doLoadDict(this.loadDict)
                !isResetPage && this.paginationReset()
                this.tableLoading = true
                const result = await this.doLoadData(this.searchMethod)
                this.tableResult = { ...result }
                this.$emit('tableLoad', this.tableResult)
                if (this._.isArray(result)) {
                    this.$set(this.table, 'data', result)
                    this.tableLoading = false
                } else if (
                    this._.isObject(result) &&
                    this._.isArray(result.data_list)
                    //  &&
                    // this._.isObject(result.page)
                ) {
                    this.tableLoading = false
                    const { data_list, page } = result
                    this.paginationUpdate({ tatal_count: result.all_num })
                    this.$set(this.table, 'data', data_list)

                    // this.all_num = result.all_num
                } else {
                    this.$set(this.table, 'data', [])
                    this.paginationReset()
                    this.tableLoading = false
                }
            } catch (error) {
                this.tableLoading = false
                console.log(error)
            }
        },
        /**
         * @description 重置搜索表单
         */
        searchFormReset() {
            this.initSearchForm()
            this.research(true)
        },
        /**
         * @description init
         * @description 合并 settingColumns
         * @description 并加上 id
         */
        async initTableColumns() {
            let columnsData = await this.getColumnSetting()
            const columns = this._.cloneDeep([...this.settingColumns])
            columnsData = this._.cloneDeep(columnsData).map(e => {
                return {
                    ...e,
                    ...(columns.find(value => {
                        return value.prop === e.prop
                    }) || {})
                }
            })
            this.table.columns = this._.cloneDeep(
                columnsData.filter(e => e.show !== false && e.if !== false)
            )
            this.columnsFilter.options = this._.cloneDeep(
                columnsData.filter(e => e.if !== false)
            )
        },
        /**
         * @description 请求表格数据
         * @param {Function} fn 请求函数 需要返回 Promise
         */
        async doLoadData(fn = () => {}) {
            this.status.isLoadingData = true
            try {
                const data = await fn()
                this.status.isLoadingData = false
                return Promise.resolve(data)
            } catch (error) {
                this.status.isLoadingData = false
                return Promise.reject(error)
            }
        },
        /**
         * @description 表格排序变化时触发
         */
        onTableSortChange({ prop, order }) {
            this.sort.prop = prop
            switch (order) {
                case 'ascending':
                    this.sort.type = 'ASC'
                    break
                case 'descending':
                    this.sort.type = 'DESC'
                    break
                default:
                    this.sort.type = ''
                    break
            }
            this.research(true)
        },
        /**
         * @description 触发列设置面板显示
         */
        tableColumnsFilterStart() {
            this.$refs['table-columns-filter'].start()
        },
        /**
         * @description init
         * @description 根据 settingSearch 初始化搜索条件
         */
        initSearchForm() {
            const data = {}
            this.settingSearch.forEach(setting => {
                data[setting.prop] = setting.default
                // [setting.prop] = setting.default
                this.$set(this.searchValue, setting.prop, setting.default)
            })
            this.$set(this.search.form, 'model', data)
            this.$set(this.search.form.model, 'model', data.theDate)
        },
        tableInit() {
            let self = this
            /* 获取头部td集合,这边是测试表格，只有一个所以直接el-table__body 的0，后续可以在<el-table> 加class，
            再用querySelector
            */
            let tblObj = document.getElementsByClassName('el-table__body')[0]
            //如果不用数组，最后遍历的时候不能有【】这个来选取元素
            let headerRows = new Array()

            for (let i = 0; i < tblObj.rows.length; i++) {
                //只有rows这个能选，col要先选rows，然后用cells
                console.log('111111', tblObj.rows[i])
                headerRows[i] = tblObj.rows[i].cells[0]
            }
            // 去头部的位置
            let headerTds = document.getElementsByClassName('el-table__body')[0]
                .rows[0].cells
            let screenYStart = 0
            let tdHeight = 0
            let headerHeight = 0

            for (let i = 0; i < headerRows.length; i++) {
                //添加头部单元格事件
                this.addListener(headerRows[i], 'mousedown', onmousedown)
                this.addListener(headerRows[i], 'mousemove', onmousemove)
            }

            document.onmousedown = function(event) {
                if (this.resizeable) {
                    let evt = event || window.event
                    this.mousedown = true
                    screenYStart = evt.screenY
                    tdHeight = this.targetTd.offsetHeight
                    headerHeight = tblObj.offsetHeight
                }
            }
            document.onmousemove = function(event) {
                let evt = event || window.event
                let srcObj = self.getTarget(evt)
                //rowIndex是未定义！！！cellIndex是好用的。我应该获取的是tr的rowindex
                //获取偏移 这里是鼠标的偏移
                let offsetY = evt.offsetY
                if (this.mousedown) {
                    let height = tdHeight + (evt.screenY - screenYStart) + 'px' //计算后的新的宽度，原始td+偏移
                    this.targetTd.style.height = height
                    tblObj.style.height =
                        headerHeight + (evt.screenY - screenYStart) + 'px'
                } else {
                    //修改光标样式，ele原来头部的不能影响，于是有一些offset位置的判断，如有更好的方式请留言
                    if (
                        srcObj.offsetHeight - evt.offsetY <= 8 &&
                        srcObj.offsetWidth - evt.offsetX > 8
                    ) {
                        this.targetTd = srcObj
                        this.resizeable = true
                        srcObj.style.cursor = 'row-resize' //修改光标样式
                    } else if (evt.offsetY <= 8 && evt.offsetX > 8) {
                        if (srcObj.parentNode.rowIndex) {
                            this.targetTd =
                                tblObj.rows[
                                    srcObj.parentNode.rowIndex - 1
                                ].cells[0]
                            this.resizeable = true
                            srcObj.style.cursor = 'row-resize'
                        }
                    } else if (
                        srcObj.offsetHeight - evt.offsetY > 8 &&
                        srcObj.offsetWidth - evt.offsetX <= 8
                    ) {
                        srcObj.style.cursor = 'column-resize' //修改光标样式
                    } else if (evt.offsetY > 8 && evt.offsetX <= 8) {
                        if (srcObj.parentNode.rowIndex) {
                            srcObj.style.cursor = 'column-resize'
                        }
                    } else {
                        this.resizeable = false
                        srcObj.style.cursor = 'default'
                    }
                }
            }
            //放开鼠标恢复原位
            document.onmouseup = function(event) {
                this.tartgetTd = null
                this.coltargetTd = null
                this.resizeable = false
                this.mousedown = false
                document.body.style.cursor = 'default'
            }
        },
        // 得到目标值事件
        getTarget(evt) {
            return evt.target || evt.srcElement
        },
        // 添加监听
        addListener(element, type, listener, useCapture) {
            //这是两种写法，对应不同浏览器
            element.addEventListener
                ? element.addEventListener(type, listener, useCapture)
                : element.attachEvent('on' + type, listener)
        }
    },
    render(createElement) {
        const propsDefault = {
            stripe: true,
            // height: '100%',
            rowKey: 'id',
            treeProps: {
                children: 'children_list'
            }
        }
        const column = this.table.columns.map(column => {
            // column.showOverflowTooltip = true
            if (this.$scopedSlots[column.prop]) {
                return createElement('el-table-column', {
                    props: column,
                    scopedSlots: {
                        default: scope => this.$scopedSlots[column.prop](scope)
                    }
                })
            } else {
                const scopedSlots = column.render
                    ? {
                          scopedSlots: {
                              default: scope => column.render(scope)
                          }
                      }
                    : null
                return createElement('el-table-column', {
                    props: column,
                    ...(scopedSlots || {})
                })
            }
        })
        if (this.selection) {
            column.unshift(
                <el-table-column
                    type="selection"
                    align="center"></el-table-column>
            )
        }
        return (
            <div class="table-component">
                {this.vNodeTableColumnsFilter}
                {this.settingSearchFilteredShow.length ||
                this.$slots.settingSearch ||
                this.$slots.default ? (
                    <div class="table-search">
                        <div class="table-action">
                            {this.$slots.default || null}
                        </div>
                        {this.$slots.settingSearch || this.vNodeSearchForm}
                    </div>
                ) : null}

                <el-table
                    data={this.table.data}
                    ref="table"
                    // on-sort-change={this.onTableSortChange}
                    props={Object.assign(propsDefault, this.$attrs)}
                    on={this.$listeners}
                    v-loading={this.tableLoading}
                    element-loading-text="数据拼命加载中"
                    element-loading-spinner="el-icon-loading">
                    {column}
                    {this.$slots.append ? (
                        <div class="append" slot="append">
                            {this.$slots.append}
                        </div>
                    ) : null}
                </el-table>

                {this.isPagination ? this.vNodePaginationMini : null}
            </div>
        )
    }
}
</script>
<style lang="scss">
.table-component {
    width: 100%;
    .el-pagination {
        background-color: #ffffff;
    }
    .table-search {
        background-color: #ffffff;
    }
    thead tr th {
        background: #f2f8ff;
        // font-size: 16px;
    }
    .table-row-action {
        font-size: 14px;
    }
    .table-row-action-flex {
        font-size: 14px;
        display: flex;
        align-items: center;
        justify-content: center;
    }
}
.table-search {
    display: flex;
    justify-content: flex-end;
    height: 50px;
    align-items: center;
    border-bottom: 2px solid rgb(71, 120, 233, 0.1);
    .table-action {
        display: flex;
        flex: auto;
        .el-button--text {
            padding: 10px 20px;
            > span {
                color: #333333;
            }
        }
    }
    .search {
        display: flex;
        align-items: center;
    }
    .el-form-item.table-search-actions {
        width: auto;
    }
    .el-form-item {
        margin-bottom: 0;
        // width: min-content;
        .el-input {
            .el-input__inner {
                border: 0;
            }
            .el-input__inner::placeholder {
                color: #333333;
            }
            /* 谷歌 */
            .el-input__inner::-webkit-input-placeholder {
                color: #333333;
            }
            /* 火狐 */
            .el-input__inner:-moz-placeholder {
                color: #333333;
            }
            /*ie*/
            .el-input__inner:-ms-input-placeholder {
                color: #333333;
            }
        }
        .el-select {
            // min-width: 100px;
        }
        .keyword {
            .el-input__inner {
                border-radius: 32px;
                border: 1px solid #cdcdcd;
            }
        }
    }
}
.tablecolumnRadio {
    .el-radio__label {
        display: none;
    }
}
</style>
